package cn.iocoder.yudao.module.iot.job.scene;

import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.quartz.core.handler.JobHandler;
import cn.iocoder.yudao.framework.tenant.core.job.TenantJob;
import cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneActionDO;
import cn.iocoder.yudao.module.iot.dal.dataobject.scene.IotSceneConditionDO;
import cn.iocoder.yudao.module.iot.dal.mysql.scene.IotSceneActionMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.scene.IotSceneMapper;
import cn.iocoder.yudao.module.iot.dal.mysql.scene.IotSceneConditionMapper;
import cn.iocoder.yudao.module.iot.service.scene.IotSceneService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Map;

/**
 * IoT 场景定时任务通用处理器
 *
 * 根据场景ID执行对应的动作
 *
 * @author 芋道源码
 */
@Component("iotSceneTimerJob")
@Slf4j
public class IotSceneTimerJobHandler implements JobHandler {

    @Resource
    private IotSceneMapper sceneMapper;
    
    @Resource
    private IotSceneActionMapper sceneActionMapper;
    
    @Resource
    private IotSceneConditionMapper sceneConditionMapper;
    
    @Resource
    private IotSceneService sceneService;

    @Override
    @TenantJob
    public String execute(String param) {
        try {
            log.info("[execute][开始执行场景定时任务，参数: {}]", param);
            
            // 解析参数
            Map<String, Object> paramMap = JsonUtils.parseObject(param, Map.class);
            Long sceneId = Long.valueOf(paramMap.get("sceneId").toString());
            
            // 获取场景信息
            IotSceneDO scene = sceneMapper.selectById(sceneId);
            if (scene == null) {
                log.error("[execute][场景不存在，场景ID: {}]", sceneId);
                return "FAILED: 场景不存在";
            }
            
            // 检查场景状态
            if (scene.getStatus() != 1) {
                log.warn("[execute][场景已禁用，场景ID: {}, 状态: {}]", sceneId, scene.getStatus());
                return "SKIPPED: 场景已禁用";
            }
            
            // 检查重复执行的时间条件
            if (!shouldExecuteScene(scene)) {
                log.info("[execute][场景不在执行时间内，跳过执行，场景ID: {}]", sceneId);
                return "SKIPPED: 不在执行时间内";
            }
            
            // 获取场景动作
            List<IotSceneActionDO> actions = sceneActionMapper.selectListBySceneId(sceneId);
            if (actions.isEmpty()) {
                log.warn("[execute][场景无动作，场景ID: {}]", sceneId);
                return "SKIPPED: 场景无动作";
            }
            
            // 执行场景
            sceneService.executeScene(sceneId, scene.getUserId());
            
            log.info("[execute][场景定时任务执行成功，场景ID: {}, 动作数量: {}]", sceneId, actions.size());
            return "SUCCESS";
            
        } catch (Exception e) {
            log.error("[execute][场景定时任务执行失败，参数: {}]", param, e);
            return "FAILED: " + e.getMessage();
        }
    }
    
    /**
     * 检查场景是否应该执行
     */
    private boolean shouldExecuteScene(IotSceneDO scene) {
        try {
            // 获取场景的定时条件
            List<IotSceneConditionDO> timerConditions = sceneConditionMapper.selectList(
                new cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX<IotSceneConditionDO>()
                    .eq(IotSceneConditionDO::getSceneId, scene.getId())
                    .eq(IotSceneConditionDO::getConditionType, "TIMER")
            );
            
            for (IotSceneConditionDO condition : timerConditions) {
                if (condition.getConditionValue() != null) {
                    try {
                        Map<String, Object> conditionValue = JsonUtils.parseObject(condition.getConditionValue(), Map.class);
                        String executionMode = (String) conditionValue.get("executionMode");
                        
                        // 单次执行：直接执行
                        if ("once".equals(executionMode)) {
                            return true;
                        }
                        
                        // 重复执行：检查当前时间是否在设置的周几内
                        if ("repeat".equals(executionMode)) {
                            @SuppressWarnings("unchecked")
                            List<Integer> selectedDays = (List<Integer>) conditionValue.get("days");
                            if (selectedDays != null && !selectedDays.isEmpty()) {
                                // 获取当前是周几（1-7，1代表周一）
                                int currentDayOfWeek = java.time.LocalDate.now().getDayOfWeek().getValue();
                                
                                // 检查当前是否在选择的周几内
                                if (selectedDays.contains(currentDayOfWeek)) {
                                    log.info("[shouldExecuteScene][重复执行场景，当前周几: {}, 选择的周几: {}, 场景ID: {}]", 
                                            currentDayOfWeek, selectedDays, scene.getId());
                                    return true;
                                } else {
                                    log.info("[shouldExecuteScene][重复执行场景，当前周几: {}, 选择的周几: {}, 跳过执行，场景ID: {}]", 
                                            currentDayOfWeek, selectedDays, scene.getId());
                                    return false;
                                }
                            }
                        }
                    } catch (Exception e) {
                        log.warn("[shouldExecuteScene][解析条件值失败，场景ID: {}, 条件ID: {}]", scene.getId(), condition.getId(), e);
                    }
                }
            }
            
            // 默认执行（兼容旧数据）
            return true;
        } catch (Exception e) {
            log.error("[shouldExecuteScene][检查场景执行条件失败，场景ID: {}]", scene.getId(), e);
            return true; // 出错时默认执行
        }
    }
} 